/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.ipti.br.tag.dao;

import org.ipti.br.tag.entity.Organization;
import org.ipti.br.tag.entity.Organization_;
import org.ipti.br.tag.entity.Personage;
import org.ipti.br.tag.entity.Personage_;
import org.ipti.br.tag.entity.enums.PersonageType;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.ipti.br.tag.util.EncryptionUtil;

/**
 *
 * @author israel
 */
@Stateless
public class PersonageFacade extends AbstractFacade<Personage> {

    @PersistenceContext(unitName = "TAG2PU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public PersonageFacade() {
        super(Personage.class);
    }

    @Override
    public void create(Personage personage) {
        getEntityManager().persist(personage);
    }

    @Override
    public void edit(Personage personage) {
        personage.setSerialNumber(null);

        getEntityManager().merge(personage);
    }

    public void editForSynchronization(Personage personage) {
        getEntityManager().merge(personage);
    }

    public Personage getPersonagePerOrganizationPersonageFather(Long organizationID, Long personageFatherID) {
        CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
        CriteriaQuery<Personage> cq = cb.createQuery(Personage.class);
        Root<Personage> from = cq.from(Personage.class);
        Predicate predicate = cb.equal(from.get(Personage_.organization).get(Organization_.id), organizationID);
        Predicate predicate2 = cb.equal(from.get(Personage_.personageFather).get(Personage_.id), personageFatherID);
        cq.orderBy(cb.asc(from.get(Personage_.name)));
        cq.where(cb.and(predicate, predicate2));

        Personage p = null;
        try {
            p = getEntityManager().createQuery(cq).getSingleResult();
        } catch (Exception e) {
            p = null;
        }
        return p;
    }
    
    public List<Personage> getAllocatedPersonage(Organization organization) {
        CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
        CriteriaQuery<Personage> cq = cb.createQuery(Personage.class);
        Root<Personage> from = cq.from(Personage.class);
        Predicate predicate = cb.equal(from.get(Personage_.organization).get(Organization_.id), organization.getId());
        Predicate predicate2 = cb.equal(from.get(Personage_.personageType), PersonageType.ALLOCATED);
        cq.where(cb.and(predicate, predicate2));
        cq.orderBy(cb.asc(from.get(Personage_.name)));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<Personage> getPersonageChildren(Long personageFatherID) {
        CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
        CriteriaQuery<Personage> cq = cb.createQuery(Personage.class);
        Root<Personage> from = cq.from(Personage.class);
        Predicate predicate = cb.equal(from.get(Personage_.personageFather).get(Personage_.id), personageFatherID);
        cq.orderBy(cb.asc(from.get(Personage_.name)));
        cq.where(cb.and(predicate));

        return getEntityManager().createQuery(cq).getResultList();

    }
    
    public List<Long> getPersonageChildrenIDs(Long personageFatherID) {
        CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
        Root<Personage> from = cq.from(Personage.class);
        cq.select(from.get(Personage_.id));
        Predicate predicate = cb.equal(from.get(Personage_.personageFather).get(Personage_.id), personageFatherID);
        cq.orderBy(cb.asc(from.get(Personage_.name)));
        cq.where(cb.and(predicate));

        return getEntityManager().createQuery(cq).getResultList();

    }
    
    public Personage getPersonageByName(String personageName) {
        CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
        CriteriaQuery<Personage> cq = cb.createQuery(Personage.class);
        Root<Personage> from = cq.from(Personage.class);
        cq.where(cb.and(cb.like(from.get(Personage_.name), personageName)));

        try {
            return getEntityManager().createQuery(cq).getSingleResult();
        } catch (Exception ex) {
            return null;
        }

    }
    
    public List<Personage> findAllOrder() {
        return findAllOrderBy(Personage_.name);
    }
}
